package com.wolfeyes.framework.springsecurity.handle;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.CredentialsExpiredException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;

import com.wolfeyes.common.constant.HttpStatusConstants;
import com.wolfeyes.common.response.ResponseResult;
import com.wolfeyes.common.utils.network.web.ResponseUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * @description SpringSecurity安全认证权限框架
 * @description 登录失败处理类,登录失败后会调用里面的方法
 * @description 登录账号密码错误等情况下,会调用的处理类
 * @see Talk is cheap, Show me the code. -- Linus Torvalds
 * @title 自定义的登录（失败）处理器
 * @author yanyljava
 * @create 2022-01-14 15:52
 */
@Slf4j
@Component
public class CustomizeAuthenticationFailureHandler implements AuthenticationFailureHandler {

	/**
	 * @title 登录失败处理逻辑
	 * @param httpServletRequest 请求
	 * @param httpServletResponse 响应
	 * @param authenticationException 这个参数是异常信息，可以根据不同的异常类返回不同的提示信息
	 * @throws IOException IO异常
	 * @throws ServletException Servlet异常
	 */

	@Override
	public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException authenticationException) throws IOException, ServletException {
		
		log.debug("自定义的登录失败处理器被调用 Start！");
		// 401 访问受限，未授权（无权限访问，尚未登录，请先登录）
		//int code = HttpStatusConstants.UNAUTHORIZED;
		//返回json数据
		ResponseResult responseResult = null;
		if (authenticationException instanceof AccountExpiredException) {
			//账号过期
			responseResult = ResponseResult.error(HttpStatusConstants.USER_ACCOUNT_EXPIRED, "账号已过期，请联系管理员!");
		//BadCredentialsException 这个异常一般是用户名或者密码错误
		} else if (authenticationException instanceof BadCredentialsException) {
			//密码错误
			responseResult = ResponseResult.error(HttpStatusConstants.USER_CREDENTIALS_ERROR, "用户名或者密码输入错误，请重新输入!");
		} else if (authenticationException instanceof CredentialsExpiredException) {
			//密码过期
			responseResult = ResponseResult.error(HttpStatusConstants.USER_CREDENTIALS_EXPIRED, "密码已过期，请联系管理员!");
		} else if (authenticationException instanceof DisabledException) {
			//账号不可用
			responseResult = ResponseResult.error(HttpStatusConstants.USER_ACCOUNT_DISABLE, "账号被禁用，请联系管理员!");
		} else if (authenticationException instanceof LockedException) {
			//账号锁定
			responseResult = ResponseResult.error(HttpStatusConstants.USER_ACCOUNT_LOCKED, "账号被锁定，请联系管理员!");
		} else if (authenticationException instanceof InternalAuthenticationServiceException) {
			//用户不存在
			responseResult = ResponseResult.error(HttpStatusConstants.USER_ACCOUNT_NOT_EXIST, "账号不存在");
		}else{
			//其他错误
			responseResult = ResponseResult.error(HttpStatusConstants.COMMON_FAIL, "其他未知错误");
		}
		httpServletResponse.setContentType("text/json;charset=utf-8");
		//resp.setContentType("application/json;charset=utf-8");
		//PrintWriter out = resp.getWriter();
		//out.write(new ObjectMapper().writeValueAsString(respBean));
		//httpServletResponse.getWriter().write(JSON.toJSONString(responseResult));
		//设置response状态码，返回错误信息等
		ResponseUtils.out(responseResult);
		log.debug("自定义的登录失败处理器被调用 End！");
	}
}


